package cn.zhentao.service.impl;

import cn.zhentao.mapper.MenuMapper;
import cn.zhentao.mapper.PermissionMapper;
import cn.zhentao.mapper.RoleMapper;
import cn.zhentao.mapper.RolePermissionMapper;
import cn.zhentao.pojo.Menu;
import cn.zhentao.pojo.Permission;
import cn.zhentao.pojo.Role;
import cn.zhentao.pojo.RolePermission;
import cn.zhentao.service.RoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author xm166
* @description 针对表【role(角色信息表)】的数据库操作Service实现
* @createDate 2025-07-28 16:25:23
*/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role>
    implements RoleService{

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public IPage<Role> getRolePage(Page<Role> page, String roleName, String status) {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();

        if (StringUtils.hasText(roleName)) {
            wrapper.like("role_name", roleName);
        }

        if (StringUtils.hasText(status)) {
            wrapper.eq("status", status);
        }

        wrapper.eq("del_flag", "0"); // 只查询未删除的角色
        wrapper.orderByAsc("role_sort");

        return roleMapper.selectPage(page, wrapper);
    }

    @Override
    public Role getRoleByKey(String roleKey) {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("role_key", roleKey);
        return roleMapper.selectOne(wrapper);
    }

    @Override
    public List<Permission> getRolePermissions(Long roleId) {
        QueryWrapper<RolePermission> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(wrapper);

        if (rolePermissions.isEmpty()) {
            return new ArrayList<>();
        }

        List<Long> permissionIds = rolePermissions.stream()
                .map(RolePermission::getPermissionId)
                .collect(Collectors.toList());

        return permissionMapper.selectBatchIds(permissionIds);
    }

    @Override
    public List<Menu> getRoleMenus(Long roleId) {
        // 通过角色权限获取菜单
        List<Permission> permissions = getRolePermissions(roleId);
        if (permissions.isEmpty()) {
            return new ArrayList<>();
        }

        List<Long> menuIds = permissions.stream()
                .map(Permission::getMenuId)
                .filter(menuId -> menuId != null)
                .distinct()
                .collect(Collectors.toList());

        if (menuIds.isEmpty()) {
            return new ArrayList<>();
        }

        return menuMapper.selectBatchIds(menuIds);
    }

    @Override
    @Transactional
    public boolean assignPermissionsToRole(Long roleId, List<Long> permissionIds) {
        // 先删除角色现有权限
        QueryWrapper<RolePermission> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.eq("role_id", roleId);
        rolePermissionMapper.delete(deleteWrapper);

        // 添加新权限
        for (Long permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionMapper.insert(rolePermission);
        }

        return true;
    }

    @Override
    @Transactional
    public boolean removeRolePermissions(Long roleId, List<Long> permissionIds) {
        QueryWrapper<RolePermission> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        wrapper.in("permission_id", permissionIds);
        return rolePermissionMapper.delete(wrapper) > 0;
    }

    @Override
    public boolean assignMenusToRole(Long roleId, List<Long> menuIds) {
        // 这个方法需要根据菜单获取对应的权限，然后分配给角色
        // 简化实现：通过菜单ID获取相关权限
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.in("menu_id", menuIds);
        List<Permission> permissions = permissionMapper.selectList(wrapper);

        List<Long> permissionIds = permissions.stream()
                .map(Permission::getPermissionId)
                .collect(Collectors.toList());

        return assignPermissionsToRole(roleId, permissionIds);
    }

    @Override
    public boolean existsByRoleName(String roleName) {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("role_name", roleName);
        return roleMapper.selectCount(wrapper) > 0;
    }

    @Override
    public boolean existsByRoleKey(String roleKey) {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("role_key", roleKey);
        return roleMapper.selectCount(wrapper) > 0;
    }

    @Override
    public List<Role> getEnabledRoles() {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("status", "0"); // 0表示正常状态
        wrapper.eq("del_flag", "0");
        wrapper.orderByAsc("role_sort");
        return roleMapper.selectList(wrapper);
    }

    @Override
    @Transactional
    public boolean deleteRolesByIds(List<Long> roleIds) {
        // 逻辑删除
        List<Role> roles = new ArrayList<>();
        for (Long roleId : roleIds) {
            Role role = new Role();
            role.setRoleId(roleId);
            role.setDelFlag("2"); // 2表示删除
            roles.add(role);
        }
        return updateBatchById(roles);
    }

    @Override
    public boolean updateRoleStatus(Long roleId, String status) {
        Role role = new Role();
        role.setRoleId(roleId);
        role.setStatus(status);
        return roleMapper.updateById(role) > 0;
    }
}




